//
//	File Name   :	Protein.cpp
//	Description :	Protein implementation file.
//	Author		:	William McVicar
//  Mail		:	mcvicar.william@gmail.com
//

//  Precompiled Header
#include "CommonDefines.h"

//  Library Includes

//  Local Includes
#ifdef PROTEIN_PLATFORM_WINDOWS
#include "PlatformWin32.h"
#include "FileSystemWin32.h"
#endif

#include "ProteinRenderer.h"
#include "Clock.h"
#include "TextureManager.h"

#ifdef PROTEIN_INCLUDE_FREEIMAGE
#include "Protein_FreeImage.h"
#endif

//  This includes
#include "ProteinFramework.h"

//	Macros

namespace Protein
{

//  Static Variables
IRenderer*		ProteinFramework::sm_pTheRenderer		  = NULL;
IPlatform*		ProteinFramework::sm_pThePlatform		  = NULL;
Clock*			ProteinFramework::sm_pTheClock			  = NULL;
IFileSystem*	ProteinFramework::sm_pTheFilesystem		  = NULL;
TextureManager* ProteinFramework::sm_pTheTextureManager	  = NULL;

bool			ProteinFramework::sm_bIsEngineInitialised = false;
//  Static Function Prototypes

//  Implementation

ProteinFramework::ProteinFramework()
{

}

ProteinFramework::~ProteinFramework()
{

}

bool ProteinFramework::IsInitialised()
{
	return sm_bIsEngineInitialised;
}

bool ProteinFramework::InitialiseEngine()
{
	if( sm_bIsEngineInitialised )
		return false;

#ifdef PROTEIN_PLATFORM_WINDOWS
  initialiseWindowsSpecific();
#else
	sm_pThePlatform = new IPlatform();
#endif

	sm_pTheTextureManager = new TextureManager();

#if defined( DX10 )
	sm_pTheRenderer = new Dx10Renderer();
#elif defined( DX11 )
	sm_pTheRenderer = new Dx11Renderer();
#elif defined( OPENGL )
	sm_pTheRenderer = new OpenGLRenderer();
#endif
	sm_pTheRenderer->Initialise( static_cast< PlatformWin32* >( sm_pThePlatform )->GetHWND() );

	sm_pTheClock = new Clock();
	sm_pTheClock->Initialise();

#ifdef PROTEIN_INCLUDE_FREEIMAGE
	FreeImage_Initialise();
#endif

	sm_bIsEngineInitialised = true;
	return true;
}

bool ProteinFramework::UninitialiseEngine()
{
#ifdef PROTEIN_INCLUDE_FREEIMAGE
	FreeImage_DeInitialise();
#endif

	delete sm_pThePlatform;
	delete sm_pTheRenderer;
	delete sm_pTheClock;
	delete sm_pTheFilesystem;
	delete sm_pTheTextureManager;

	return true;
}

void ProteinFramework::Run()
{
	sm_pTheClock->Update();
}

IRenderer& ProteinFramework::renderer()
{
	return *sm_pTheRenderer;
}

IPlatform& ProteinFramework::platform()
{
	return *sm_pThePlatform;
}

Clock& ProteinFramework::clock()
{
	return *sm_pTheClock;
}

IFileSystem& ProteinFramework::fileSystem()
{
	return *sm_pTheFilesystem;
}

TextureManager& ProteinFramework::textureManager()
{
	return *sm_pTheTextureManager;
}

#ifdef PROTEIN_PLATFORM_WINDOWS
void ProteinFramework::initialiseWindowsSpecific()
{
  sm_pThePlatform = new PlatformWin32();
	sm_pThePlatform->Initialise();

	sm_pTheFilesystem = new FileSystemWin32();
}
#endif

}